// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.erosion.categories;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import zombie.debug.DebugLog;
import zombie.erosion.ErosionData;
import zombie.erosion.ErosionMain;
import zombie.erosion.ErosionRegions;
import zombie.erosion.obj.ErosionObj;
import zombie.erosion.season.ErosionSeason;
import zombie.iso.IsoDirections;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;
import zombie.iso.SpriteDetails.IsoFlagType;

public abstract class ErosionCategory {
    public int ID;
    public ErosionRegions.Region region;
    protected ErosionCategory.SeasonDisplay[] seasonDisp = new ErosionCategory.SeasonDisplay[6];

    public ErosionCategory() {
        for (int _int = 0; _int < 6; _int++) {
            this.seasonDisp[_int] = new ErosionCategory.SeasonDisplay();
        }
    }

    protected ErosionCategory.Data getCatModData(ErosionData.Square square) {
        for (int _int = 0; _int < square.regions.size(); _int++) {
            ErosionCategory.Data data = (ErosionCategory.Data)square.regions.get(_int);
            if (data.regionID == this.region.ID && data.categoryID == this.ID) {
                return data;
            }
        }

        return null;
    }

    protected ErosionCategory.Data setCatModData(ErosionData.Square square) {
        ErosionCategory.Data data = this.getCatModData(square);
        if (data == null) {
            data = this.allocData();
            data.regionID = this.region.ID;
            data.categoryID = this.ID;
            square.regions.add(data);
            if (square.regions.size() > 5) {
                DebugLog.log("> 5 regions on a square");
            }
        }

        return data;
    }

    protected IsoObject validWall(IsoGridSquare isoGridSquare0, boolean boolean0, boolean boolean1) {
        if (isoGridSquare0 == null) {
            return null;
        } else {
            IsoGridSquare isoGridSquare1 = boolean0 ? isoGridSquare0.getTileInDirection(IsoDirections.N) : isoGridSquare0.getTileInDirection(IsoDirections.W);
            Object object = null;
            if (isoGridSquare0.isWallTo(isoGridSquare1)) {
                if (boolean0 && isoGridSquare0.Is(IsoFlagType.cutN) && !isoGridSquare0.Is(IsoFlagType.canPathN)
                    || !boolean0 && isoGridSquare0.Is(IsoFlagType.cutW) && !isoGridSquare0.Is(IsoFlagType.canPathW)) {
                    object = isoGridSquare0.getWall(boolean0);
                }
            } else if (boolean1 && (isoGridSquare0.isWindowBlockedTo(isoGridSquare1) || isoGridSquare0.isWindowTo(isoGridSquare1))) {
                object = isoGridSquare0.getWindowTo(isoGridSquare1);
                if (object == null) {
                    object = isoGridSquare0.getWall(boolean0);
                }
            }

            if (object != null) {
                if (isoGridSquare0.getZ() > 0) {
                    String string = ((IsoObject)object).getSprite().getName();
                    return (IsoObject)(string != null && !string.contains("roof") ? object : null);
                } else {
                    return (IsoObject)object;
                }
            } else {
                return null;
            }
        }
    }

    protected float clerp(float float1, float float3, float float2) {
        float float0 = (float)(1.0 - Math.cos((double)float1 * Math.PI)) / 2.0F;
        return float3 * (1.0F - float0) + float2 * float0;
    }

    protected int currentSeason(float float4, ErosionObj var2) {
        int int0 = 0;
        ErosionSeason erosionSeason = ErosionMain.getInstance().getSeasons();
        int int1 = erosionSeason.getSeason();
        float float0 = erosionSeason.getSeasonDay();
        float float1 = erosionSeason.getSeasonDays();
        float float2 = float1 / 2.0F;
        float float3 = float2 * float4;
        ErosionCategory.SeasonDisplay seasonDisplay0 = this.seasonDisp[int1];
        if (seasonDisplay0.split && float0 >= float2 + float3) {
            int0 = seasonDisplay0.season2;
        } else if ((!seasonDisplay0.split || !(float0 >= float3)) && !(float0 >= float1 * float4)) {
            ErosionCategory.SeasonDisplay seasonDisplay1;
            if (int1 == 5) {
                seasonDisplay1 = this.seasonDisp[4];
            } else if (int1 == 1) {
                seasonDisplay1 = this.seasonDisp[5];
            } else if (int1 == 2) {
                seasonDisplay1 = this.seasonDisp[1];
            } else {
                seasonDisplay1 = this.seasonDisp[2];
            }

            if (seasonDisplay1.split) {
                int0 = seasonDisplay1.season2;
            } else {
                int0 = seasonDisplay1.season1;
            }
        } else {
            int0 = seasonDisplay0.season1;
        }

        return int0;
    }

    protected boolean currentBloom(float float4, ErosionObj erosionObj) {
        boolean _boolean = false;
        ErosionSeason erosionSeason = ErosionMain.getInstance().getSeasons();
        int _int = erosionSeason.getSeason();
        if (erosionObj.hasFlower && _int == 2) {
            float float0 = erosionSeason.getSeasonDay();
            float float1 = erosionSeason.getSeasonDays();
            float float2 = float1 / 2.0F;
            float float3 = float2 * float4;
            float float5 = float1 - float3;
            float float6 = float0 - float3;
            float float7 = float5 * erosionObj.bloomEnd;
            float float8 = float5 * erosionObj.bloomStart;
            float float9 = (float7 - float8) / 2.0F;
            float float10 = float9 * float4;
            float7 = float8 + float9 + float10;
            float8 += float10;
            if (float6 >= float8 && float6 <= float7) {
                _boolean = true;
            }
        }

        return _boolean;
    }

    public void updateObj(
        ErosionData.Square _sqErosionData,
        ErosionCategory.Data _sqCategoryData,
        IsoGridSquare _sq,
        ErosionObj _gameObj,
        boolean _bTree,
        int _stage,
        int _dispSeason,
        boolean _bloom
    ) {
        if (!_sqCategoryData.hasSpawned) {
            if (!_gameObj.placeObject(_sq, _stage, _bTree, _dispSeason, _bloom)) {
                this.clearCatModData(_sqErosionData);
                return;
            }

            _sqCategoryData.hasSpawned = true;
        } else if (_sqCategoryData.stage != _stage || _sqCategoryData.dispSeason != _dispSeason || _sqCategoryData.dispBloom != _bloom) {
            IsoObject isoObject = _gameObj.getObject(_sq, false);
            if (isoObject == null) {
                this.clearCatModData(_sqErosionData);
                return;
            }

            _gameObj.setStageObject(_stage, isoObject, _dispSeason, _bloom);
        }

        _sqCategoryData.stage = _stage;
        _sqCategoryData.dispSeason = _dispSeason;
        _sqCategoryData.dispBloom = _bloom;
    }

    protected void clearCatModData(ErosionData.Square square) {
        for (int _int = 0; _int < square.regions.size(); _int++) {
            ErosionCategory.Data data = (ErosionCategory.Data)square.regions.get(_int);
            if (data.regionID == this.region.ID && data.categoryID == this.ID) {
                square.regions.remove(_int);
                return;
            }
        }
    }

    public abstract void init();

    public abstract boolean replaceExistingObject(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall
    );

    public abstract boolean validateSpawn(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall, boolean _isRespawn
    );

    public abstract void update(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionCategory.Data _sqCategoryData, ErosionData.Chunk _chunkData, int _eTick
    );

    protected abstract ErosionCategory.Data allocData();

    public static ErosionCategory.Data loadCategoryData(ByteBuffer input, int WorldVersion) {
        byte byte0 = input.get();
        byte byte1 = input.get();
        ErosionCategory erosionCategory = ErosionRegions.getCategory(byte0, byte1);
        ErosionCategory.Data data = erosionCategory.allocData();
        data.regionID = byte0;
        data.categoryID = byte1;
        data.load(input, WorldVersion);
        return data;
    }

    public abstract void getObjectNames(ArrayList<String> list);

    public static class Data {
        public int regionID;
        public int categoryID;
        public boolean doNothing;
        public boolean hasSpawned;
        public int stage;
        public int dispSeason;
        public boolean dispBloom;

        public void save(ByteBuffer output) {
            byte _byte = 0;
            if (this.doNothing) {
                _byte = (byte)(_byte | 1);
            }

            if (this.hasSpawned) {
                _byte = (byte)(_byte | 2);
            }

            if (this.dispBloom) {
                _byte = (byte)(_byte | 4);
            }

            if (this.stage == 1) {
                _byte = (byte)(_byte | 8);
            } else if (this.stage == 2) {
                _byte = (byte)(_byte | 16);
            } else if (this.stage == 3) {
                _byte = (byte)(_byte | 32);
            } else if (this.stage == 4) {
                _byte = (byte)(_byte | 64);
            } else if (this.stage > 4) {
                _byte = (byte)(_byte | 128);
            }

            output.put((byte)this.regionID);
            output.put((byte)this.categoryID);
            output.put((byte)this.dispSeason);
            output.put(_byte);
            if (this.stage > 4) {
                output.put((byte)this.stage);
            }
        }

        public void load(ByteBuffer input, int WorldVersion) {
            this.stage = 0;
            this.dispSeason = input.get();
            byte _byte = input.get();
            this.doNothing = (_byte & 1) != 0;
            this.hasSpawned = (_byte & 2) != 0;
            this.dispBloom = (_byte & 4) != 0;
            if ((_byte & 8) != 0) {
                this.stage = 1;
            } else if ((_byte & 16) != 0) {
                this.stage = 2;
            } else if ((_byte & 32) != 0) {
                this.stage = 3;
            } else if ((_byte & 64) != 0) {
                this.stage = 4;
            } else if ((_byte & 128) != 0) {
                this.stage = input.get();
            }
        }
    }

    protected class SeasonDisplay {
        int season1;
        int season2;
        boolean split;
    }
}
